
package com.zcp.notepad;

import com.zcp.notepad.NotePad.Notes;
import com.zcp.notepad.NotePad.WidgetInfo;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;

public abstract class NoteWidgetProvider extends AppWidgetProvider {

    private static final String[] PROJECTION = new String[] {
            WidgetInfo.WIDGET_ID, // 0
            WidgetInfo.NOTE_ID, // 1
            WidgetInfo.WIDGET_SIZE, // 2
    };

    private static final int COLUMN_INDEX_WIDGET_ID = 0;

    private static final int COLUMN_INDEX_NOTE_ID = 1;

    private static final int COLUMN_INDEX_WIDGET_SIZE = 2;

    private static final String[] NOTE_PROJECTION = new String[] {
            Notes._ID, // 0
            Notes.NOTE, // 1
            Notes.LOCK, // 2
            Notes.COLOR,// 3
            Notes.MODIFIED_DATE,// 4
    };

    private static final int COLUMN_INDEX_NOTE = 1;

    private static final int COLUMN_INDEX_LOCK = 2;

    private static final int COLUMN_INDEX_COLOR = 3;

    private static final int COLUMN_INDEX_MODIFIED = 4;

    public static final String ACTION_UPDATE_BY_WIDGETID = "com.zcp.notepad.action.updateByWidgetId";

    public static final String ACTION_UPDATE_BY_NOTE = "com.zcp.notepad.action.updateByNote";

    private static final String TAG = "NoteWidgetProviders";

    Cursor mCursor;

    /**
     * 获取widget的尺寸
     * 
     * @return
     */
    protected abstract int getWidgetSize();

    /**
     * 获取Remoteviews，不同尺寸widget对应的RemoteViews不同，故由继承的类自己指定
     * 
     * @param context
     * @return
     */
    protected abstract RemoteViews getRemoteViews(Context context);

    /**
     * 获取颜色所对应的背景资源id
     * 
     * @param color NotePad.Color中对应的颜色
     * @return 资源文件ID
     */
    protected abstract int getWidgetBackgroundResoures(String color);

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            updateWidget(appWidgetManager, context, getNoteIdByWidgetId(context, appWidgetId),
                    appWidgetId, getWidgetSize());
        }

    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        Uri uri = WidgetInfo.CONTENT_URI;
        for (int appWidgetId : appWidgetIds) {
            uri = ContentUris.withAppendedId(uri, appWidgetId);
            context.getContentResolver().delete(uri, null, null);
        }
    }

    protected void updateWidgetByNote(AppWidgetManager appWidgetManager, Context context, Note note) {
        Cursor c = context.getContentResolver().query(WidgetInfo.CONTENT_URI, PROJECTION,
                WidgetInfo.NOTE_ID + "=" + note.id, null, null);

        if (c != null) {
            while (c.moveToNext()) {
                int appWidgetId = c.getInt(COLUMN_INDEX_WIDGET_ID);
                int widgetSize = c.getInt(COLUMN_INDEX_WIDGET_SIZE);
                updateWidget(appWidgetManager, context, note, appWidgetId, widgetSize);
            }
            c.close();
        }
    }

    protected int getNoteIdByWidgetId(Context context, int appWidgetId) {
        int noteId = -1;
        Uri uri = ContentUris.withAppendedId(WidgetInfo.CONTENT_URI, appWidgetId);
        Cursor cursor = context.getContentResolver().query(uri, PROJECTION, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                noteId = cursor.getInt(COLUMN_INDEX_NOTE_ID);
            }
            cursor.close();
        }
        return noteId;
    }

    protected RemoteViews buildWidgetRemoteView(AppWidgetManager appWidgetManager, Context context,
            int appWidgetId, long noteId) {

        RemoteViews rv = getRemoteViews(context);
        Intent intent = new Intent();
        if (noteId != -1) {
            intent.setClass(context, NoteEditorActivity.class);
            intent.setData(ContentUris.withAppendedId(Notes.CONTENT_URI, noteId));
            intent.setAction(Intent.ACTION_EDIT);

        } else {
            intent.setClass(context, NoteListActivity.class);
        }
        intent.putExtra("widget_id", appWidgetId);
        intent.putExtra("widget_size", getWidgetSize());
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setOnClickPendingIntent(R.id.widgetBackground, pendingIntent);
        return rv;
    }

    /**
     * 更新widget
     * 
     * @param appWidgetManager
     * @param context
     * @param noteId
     * @param appWidgetId
     * @param appWidgetSize
     */
    protected void updateWidget(AppWidgetManager appWidgetManager, Context context, int noteId,
            int appWidgetId, int appWidgetSize) {
        if (appWidgetSize != getWidgetSize()) {
            return;
        }
        if (noteId == -1) {
            noteId = getNoteIdByWidgetId(context, appWidgetId);
        }
        RemoteViews rv = buildWidgetRemoteView(appWidgetManager, context, appWidgetId, noteId);
        if (noteId != -1) {
            mCursor = context.getContentResolver().query(
                    ContentUris.withAppendedId(Notes.CONTENT_URI, noteId), NOTE_PROJECTION, null,
                    null, null);
            if (mCursor.moveToFirst()) {
                String color = mCursor.getString(COLUMN_INDEX_COLOR);
                boolean lock = mCursor.getInt(COLUMN_INDEX_LOCK) == 1 ? true : false;
                if (lock) {
                    rv.setViewVisibility(R.id.widgetLockImage, View.VISIBLE);
                    rv.setViewVisibility(R.id.widgetText, View.GONE);
                } else {
                    rv.setViewVisibility(R.id.widgetText, View.VISIBLE);
                    rv.setViewVisibility(R.id.widgetLockImage, View.GONE);
                    rv.setTextViewText(R.id.widgetText, mCursor.getString(COLUMN_INDEX_NOTE));
                }
                long time = mCursor.getLong(COLUMN_INDEX_MODIFIED);
                String timeStr = Util.getDateStr(context, time) + " "
                        + Util.getTimeStr(context, time);
                rv.setTextViewText(R.id.widgetNoteTime, timeStr);
                rv.setImageViewResource(R.id.widgetBackground,
                        this.getWidgetBackgroundResoures(color));

            }
            mCursor.close();
        } else {
            rv.setViewVisibility(R.id.widgetText, View.VISIBLE);
            rv.setViewVisibility(R.id.widgetLockImage, View.GONE);
            rv.setTextViewText(R.id.widgetNoteTime, "");
            rv.setTextViewText(R.id.widgetText, context.getString(R.string.widget_tip));
            rv.setImageViewResource(R.id.widgetBackground,
                    this.getWidgetBackgroundResoures(Notes.Color.ORANGE));
        }

        appWidgetManager.updateAppWidget(appWidgetId, rv);
    }

    protected void updateWidget(AppWidgetManager appWidgetManager, Context context, Note note,
            int appWidgetId, int appWidgetSize) {
        if (appWidgetSize != getWidgetSize()) {
            return;
        }

        // printData(context);
        RemoteViews rv = buildWidgetRemoteView(appWidgetManager, context, appWidgetId, note.id);
        if (note.isLock) {
            rv.setViewVisibility(R.id.widgetLockImage, View.VISIBLE);
            rv.setViewVisibility(R.id.widgetText, View.GONE);
        } else {
            rv.setViewVisibility(R.id.widgetText, View.VISIBLE);
            rv.setViewVisibility(R.id.widgetLockImage, View.GONE);
            rv.setTextViewText(R.id.widgetText, note.content);

        }
        String timeStr = Util.getDateStr(context, note.modified) + " "
                + Util.getTimeStr(context, note.modified);
        rv.setTextViewText(R.id.widgetNoteTime, timeStr);
        rv.setImageViewResource(R.id.widgetBackground, this.getWidgetBackgroundResoures(note.color));
        appWidgetManager.updateAppWidget(appWidgetId, rv);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_UPDATE_BY_WIDGETID.equals(action)) {
            int appWidgetId = intent.getIntExtra("widget_id", -1);
            int appWidgetSize = intent.getIntExtra("widget_size", -1);
            int noteId = intent.getIntExtra("note_id", -1);
            if (appWidgetId != -1) {
                updateWidget(AppWidgetManager.getInstance(context), context, noteId, appWidgetId,
                        appWidgetSize);
            }
        } else if (ACTION_UPDATE_BY_NOTE.equals(action)) {
            Note note = (Note) intent.getSerializableExtra("note");
            if (note != null) {
                updateWidgetByNote(AppWidgetManager.getInstance(context), context, note);
            }

        }

        super.onReceive(context, intent);
    }

    private void printData(Context context) {
        Cursor c = context.getContentResolver().query(WidgetInfo.CONTENT_URI, PROJECTION, null,
                null, null);
        if (c != null) {
            StringBuilder sb = new StringBuilder();
            for (String columnName : c.getColumnNames()) {
                sb.append(columnName).append(" ");
            }
            sb.append("\n");
            while (c.moveToNext()) {
                for (String columnName : c.getColumnNames()) {
                    sb.append(c.getString(c.getColumnIndex(columnName))).append(" ");
                }
                sb.append("\n");
            }
            c.close();
            Log.i(TAG, sb.toString());
        }
    }
}
